<?php
namespace Shopiuu;

use Shopiuu\Http\RequestCore;
use Shopiuu\Core\ShopiuuException;
use Shopiuu\Http\RequestException;

use Shopiuu\Core\Result;
use Shopiuu\Model\Article;
use Shopiuu\Model\ArticleCategory;
use Shopiuu\Model\Currency;
use Shopiuu\Model\Nav;
use Shopiuu\Model\Payment;
use Shopiuu\Model\Product;
use Shopiuu\Model\Seo;
use Shopiuu\Model\Settings;
use Shopiuu\Model\Shipping;
use Shopiuu\Model\ShippingArea;
use Shopiuu\Model\ShippingCompany;
use Shopiuu\Model\StoreTheme;
use Shopiuu\Model\EmbedCode;

class ShopiuuClient
{
    public function __construct($accessToken, $endpoint)
    {
        $accessToken = trim($accessToken);
        $endpoint = trim(trim($endpoint), "/");

        if (empty($accessToken)) {
            throw new ShopiuuException("access token id is empty");
        }
        if (empty($endpoint)) {
            throw new ShopiuuException("endpoint is empty");
        }

        $this->accessToken = $accessToken;
        $this->endpoint = $endpoint;
    }

    public function addArticle($data)
    {
        $articleModel = new Article($this->accessToken, $this->endpoint);
        try {
            $response = $articleModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateArticle($data)
    {
        $articleModel = new Article($this->accessToken, $this->endpoint);
        try {
            $response = $articleModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getArticles($data)
    {
        $articleModel = new Article($this->accessToken, $this->endpoint);
        try {
            $response = $articleModel->getList($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getArticleCategories()
    {
        $articleCategoryModel = new ArticleCategory($this->accessToken, $this->endpoint);
        try {
            $response = $articleCategoryModel->getCategories();
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getArticleCategoryTree()
    {
        $articleCategoryModel = new ArticleCategory($this->accessToken, $this->endpoint);
        try {
            $response = $articleCategoryModel->getCategoryTree();
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addArticleCategory($data)
    {
        $articleCategoryModel = new ArticleCategory($this->accessToken, $this->endpoint);
        try {
            $response = $articleCategoryModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getStoreThemes()
    {
        $storeThemeModel = new StoreTheme($this->accessToken, $this->endpoint);
        try {
            $response = $storeThemeModel->getList();
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getThemeFiles($data)
    {
        $storeThemeModel = new StoreTheme($this->accessToken, $this->endpoint);
        try {
            $response = $storeThemeModel->getThemeFiles($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function createTheme($data)
    {
        $storeThemeModel = new StoreTheme($this->accessToken, $this->endpoint);
        try {
            $response = $storeThemeModel->createTheme($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addCurrency($data)
    {
        $currencyModel = new Currency($this->accessToken, $this->endpoint);
        try {
            $response = $currencyModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateCurrency($data)
    {
        $currencyModel = new Currency($this->accessToken, $this->endpoint);
        try {
            $response = $currencyModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function deleteCurrency($data)
    {
        $currencyModel = new Currency($this->accessToken, $this->endpoint);
        try {
            $response = $currencyModel->delete($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getCurrencies($data)
    {
        $currencyModel = new Currency($this->accessToken, $this->endpoint);
        try {
            $response = $currencyModel->getList($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addEmbedCode($data)
    {
        $embedCodeModel = new EmbedCode($this->accessToken, $this->endpoint);
        try {
            $response = $embedCodeModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateEmbedCode($data)
    {
        $embedCodeModel = new EmbedCode($this->accessToken, $this->endpoint);
        try {
            $response = $embedCodeModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function deleteEmbedCode($data)
    {
        $embedCodeModel = new EmbedCode($this->accessToken, $this->endpoint);
        try {
            $response = $embedCodeModel->delete($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getEmbedCodes($data)
    {
        $embedCodeModel = new EmbedCode($this->accessToken, $this->endpoint);
        try {
            $response = $embedCodeModel->getList($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getNavMenu()
    {
        $navModel = new Nav($this->accessToken, $this->endpoint);
        try {
            $response = $navModel->getNavMenu();
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getAllNavLists()
    {
        $navModel = new Nav($this->accessToken, $this->endpoint);
        try {
            $response = $navModel->getAllNavLists();
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addNav($data)
    {
        $navModel = new Nav($this->accessToken, $this->endpoint);
        try {
            $response = $navModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateNav($data)
    {
        $navModel = new Nav($this->accessToken, $this->endpoint);
        try {
            $response = $navModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addNavMenu($data)
    {
        $navModel = new Nav($this->accessToken, $this->endpoint);
        try {
            $response = $navModel->addMenu($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateNavMenu($data)
    {
        $navModel = new Nav($this->accessToken, $this->endpoint);
        try {
            $response = $navModel->updateMenu($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function deleteNav($data)
    {
        $navModel = new Nav($this->accessToken, $this->endpoint);
        try {
            $response = $navModel->deleteNav($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function deleteNavMenu($data)
    {
        $navModel = new Nav($this->accessToken, $this->endpoint);
        try {
            $response = $navModel->deleteMenu($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getNavMenuLists($data)
    {
        $navModel = new Nav($this->accessToken, $this->endpoint);
        try {
            $response = $navModel->menuLists($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addPayment($data)
    {
        $paymentModel = new Payment($this->accessToken, $this->endpoint);
        try {
            $response = $paymentModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updatePayment($data)
    {
        $paymentModel = new Payment($this->accessToken, $this->endpoint);
        try {
            $response = $paymentModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function deletePayment($data)
    {
        $paymentModel = new Payment($this->accessToken, $this->endpoint);
        try {
            $response = $paymentModel->delete($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getPayments($data)
    {
        $paymentModel = new Payment($this->accessToken, $this->endpoint);
        try {
            $response = $paymentModel->getList($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getAllPayments($data)
    {
        $paymentModel = new Payment($this->accessToken, $this->endpoint);
        try {
            $response = $paymentModel->getAllPayments($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addProduct($data)
    {
        $productModel = new Product($this->accessToken, $this->endpoint);
        try {
            $response = $productModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateProduct($data)
    {
        $productModel = new Product($this->accessToken, $this->endpoint);
        try {
            $response = $productModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function deleteProduct($data)
    {
        $productModel = new Product($this->accessToken, $this->endpoint);
        try {
            $response = $productModel->delete($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getProducts($data)
    {
        $productModel = new Product($this->accessToken, $this->endpoint);
        try {
            $response = $productModel->getList($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateSeo($data)
    {
        $seoModel = new Seo($this->accessToken, $this->endpoint);
        try {
            $response = $seoModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getSeos($data)
    {
        $seoModel = new Seo($this->accessToken, $this->endpoint);
        try {
            $response = $seoModel->getList($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateSettings($data)
    {
        $settingsModel = new Settings($this->accessToken, $this->endpoint);
        try {
            $response = $settingsModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getSettings()
    {
        $settingsModel = new Settings($this->accessToken, $this->endpoint);
        try {
            $response = $settingsModel->getSettings();
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addShipping($data)
    {
        $shippingModel = new Shipping($this->accessToken, $this->endpoint);
        try {
            $response = $shippingModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateShipping($data)
    {
        $shippingModel = new Shipping($this->accessToken, $this->endpoint);
        try {
            $response = $shippingModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function deleteShipping($data)
    {
        $shippingModel = new Shipping($this->accessToken, $this->endpoint);
        try {
            $response = $shippingModel->delete($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getShippings($data)
    {
        $shippingModel = new Shipping($this->accessToken, $this->endpoint);
        try {
            $response = $shippingModel->getList($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getAllShippings($data)
    {
        $shippingModel = new Shipping($this->accessToken, $this->endpoint);
        try {
            $response = $shippingModel->getAllShippings($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addShippingArea($data)
    {
        $shippingAreaModel = new ShippingArea($this->accessToken, $this->endpoint);
        try {
            $response = $shippingAreaModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateShippingArea($data)
    {
        $shippingAreaModel = new ShippingArea($this->accessToken, $this->endpoint);
        try {
            $response = $shippingAreaModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function deleteShippingArea($data)
    {
        $shippingAreaModel = new ShippingArea($this->accessToken, $this->endpoint);
        try {
            $response = $shippingAreaModel->delete($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getShippingAreas($data)
    {
        $shippingAreaModel = new ShippingArea($this->accessToken, $this->endpoint);
        try {
            $response = $shippingAreaModel->getList($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function addShippingCompany($data)
    {
        $shippingCompanyModel = new ShippingCompany($this->accessToken, $this->endpoint);
        try {
            $response = $shippingCompanyModel->add($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function updateShippingCompany($data)
    {
        $shippingCompanyModel = new ShippingCompany($this->accessToken, $this->endpoint);
        try {
            $response = $shippingCompanyModel->update($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function deleteShippingCompany($data)
    {
        $shippingCompanyModel = new ShippingCompany($this->accessToken, $this->endpoint);
        try {
            $response = $shippingCompanyModel->delete($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }

    public function getShippingCompanies($data)
    {
        $shippingCompanyModel = new ShippingCompany($this->accessToken, $this->endpoint);
        try {
            $response = $shippingCompanyModel->getList($data);
            $result = new Result($response);
            return $result;
        } catch (RequestException $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        } catch (\Exception $e) {
            throw new ShopiuuException("Request error: ".$e->getMessage());
        }
    }
}